﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Prism.WebBuilder.Processors.Base;
using System.IO;
using Prism.WebBuilder.Lib.IO;
using Prism.WebBuilder.Lib.Cui;

namespace Prism.WebBuilder.Processors
{
	public class FileSet : ProcessorBase, ISource
	{
		private List<ISourceItem> _items;
		private string _name;

		public FileSet()
		{
			_items = new List<ISourceItem>();
		}

		public FileSet Init(string fileSetName)
		{
			RegisterObject(fileSetName, this);
			_name = fileSetName;
			return this;
		}

		public FileSet Add(string path)
		{
			IObject obj = GetObject(path);
			if (obj != null)
			{
				if (obj is ISource)
					_items.Add(obj as ISourceItem);
			}
			else
			{
				foreach (var pathItem in PathHelper.FindFiles(path))
					_items.Add(new FileSourceItem(pathItem, ResolvePath(path)));
			}
			return this;
		}

		public FileSet Add(ISource source)
		{
			_items.Add(source);
			return this;
		}

		public IEnumerable<ISourceItem> GetItems()
		{
			foreach (var item in _items)
			{
				if (item is ISource)
				{
					foreach (var source in (item as ISource).GetItems())
						yield return source;
				}
				else
					yield return item;
			}
		}

		public void Trace(TracingOptions options)
		{
			foreach (var item in _items)
			{
				if (item is FileSourceItem)
				{
					var f = item as FileSourceItem;
					Console.WriteLine(f.Name + ":" + f.FullPath);
				}
				else if (item is IObject)
				{
					(item as IObject).Trace(options);
				}
			}

		}

		#region Nested Classes

		public class FileSourceItem : ISourceItem, ITextContentProvider, IBinaryContentProvider, IObjectWithDependancyTag
		{
			private string _path;
			private string _fullPath;
			private string _textContent;
			private byte[] _binaryContent;
			private bool _textContentReaded;
			private bool _binaryContentReaded;
			private string _dependencyTag;

			public FileSourceItem(string path, string fullePath)
			{
				_path = path;
				_fullPath = fullePath;
			}

			public string Name { get { return _path; } }

			public string FullPath
			{
				get { return _fullPath; }
			}

			public string TextContent
			{
				get
				{
					if (!_textContentReaded)
					{
						if (File.Exists(_fullPath))
						{
							_textContent = File.ReadAllText(_fullPath);
							_textContentReaded = true;
						}
						else
						{
							Cui.Error("source {0} not found", _path);
						}

					}
					return _textContent;
				}
			}
			public byte[] BinaryContent
			{
				get
				{
					if (!_binaryContentReaded)
					{
						_binaryContent = File.ReadAllBytes(_fullPath);
						_binaryContentReaded = true;
					}
					return _binaryContent;
				}
			}


			public string DependencyTag
			{
				get
				{
					if (string.IsNullOrEmpty(_dependencyTag))
						_dependencyTag = Convert.ToBase64String(BitConverter.GetBytes(new FileInfo(_fullPath).LastWriteTime.ToBinary()));
					return _dependencyTag;
				}
			}
		}
		#endregion

		public string Name
		{
			get { return _name; }
		}
	}
}
